package cn.e2win.biz.base;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ModelAndView;

import cn.e2win.base.controller.CommonExceptionController;
import cn.e2win.base.controller.TimeEditor;
import cn.e2win.base.entity.SysAttach;
import cn.e2win.base.entity.SysUser;
import cn.e2win.base.json.vo.Pager;
import cn.e2win.biz.annotation.PageParam;
import cn.e2win.biz.comm.MyX509TrustManager;
import cn.e2win.biz.comm.ViewExcel;
import cn.e2win.biz.sys.Dict;
import cn.e2win.biz.util.StringUtils;
import cn.e2win.biz.util.WeixinUtils;
import net.sf.json.JSONObject;


public abstract class BaseController extends CommonExceptionController implements InitializingBean{

	public static final String IDS = "ids";
	public static final String ID = "id";
	public static final String TYPE = "type";
	public static final String ENTITY = "entity";
	public static final String FUNID = "FUNID";
	public static final String ACTION = "ACTION";
	public static final String TODO = "TODO";
	public static final String MODULE = "module";
	public static final String OBJECT = "object";
	public static final String ITEMS = "items.";
	public static final String LOGS_LIST = "logsList";

	public static final String USER = "user";

	public String todo = "";
	public String action  ="";
	public String funId = "";
	
	public Pager pager = new Pager();
	
	private BaseService service;

	public abstract BaseService initService();


	@Override
	public void afterPropertiesSet() throws Exception {
		this.service = initService();
	}

	public String toSelectJSP(String selectName, List<Map<String, Object>> list, String value, String text, ModelMap modelMap){
		modelMap.put("name", selectName);
		modelMap.put("list", list);
		modelMap.put("value", value);
		modelMap.put("text", text);
		return "comm/include_select";
	}




	@InitBinder
    public void initDataBinder(WebDataBinder binder) {
        TimeEditor timeEditor = new TimeEditor();
        //也可以是日期格式：timeEditor.setFormat("yyyy-MM-dd");
        //但必须与页面input的handleTime输入框格式一致，否则保存指定的日期会失败。
        binder.registerCustomEditor(Date.class, "handleTime", timeEditor);
         //其他方法
        //DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //CustomDateEditor dateEditor = new CustomDateEditor(fmt, true);
        //binder.registerCustomEditor(Date.class, dateEditor);
        //super.initBinder(request, binder);
    }

	@ModelAttribute
	public void initParam(HttpServletRequest request, @PageParam Pager pager, ModelMap modelMap){
		//Map<String, Object> userSession = (Map<String, Object>)request.getSession().getAttribute("USER");
		//pager.getScMap().put("coId", userSession.get("coId")==null?null:userSession.get("coId").toString());

		if(Dict.getRealPath()==null){
			Dict.setRealPath(request.getSession().getServletContext().getRealPath("/"));
		}

		funId = request.getParameter(FUNID)==null?"":request.getParameter(FUNID);
		modelMap.put(FUNID, funId);

		//ACTION 的值人ADD,DEL,MODIFY,VIEW（增，删，改，查）  主要用于控制对象元素的读写状态
		action = request.getParameter(ACTION)==null?"VIEW":request.getParameter(ACTION);
		modelMap.put(ACTION, action);

		//TODO 的值为EDIT, SUBMIT, APPROVE, PAY等（编辑，提交，审核，付款）  主要用于控制操作按钮的展示与否状态，以及用于设置状态的过滤条件
		todo = request.getParameter(TODO);
		modelMap.put(TODO, todo);
		
		if("INC_PAGER".equals(todo)){
			pager.setReturnAll(true);
		}

		SysUser user = (SysUser)request.getSession().getAttribute("user");
		pager.setCurrUser(user);
		if(!pager.getScMap().containsKey("activeStatusInt")){
			pager.getScMap().put("activeStatusInt", "1");
		}
		this.pager = pager;
		//TODO 此方法需要优化
        modelMap.putAll(WeixinUtils.getWxConfig(request));
	}

    public ModelAndView viewExcel(HttpServletRequest request,  @PageParam Pager pager) {
        Map model = new HashMap();
        System.err.println(pager.getSql());
        model.put("list", pager.getResultList());
        return new ModelAndView(new ViewExcel(), model);
    }
	public Object processView(HttpServletRequest request, @PageParam Pager pager, String viewTemplate){
		String returnType = request.getParameter("RETURN_TYPE");
		if("EXCEL".equals(returnType)){
			return viewExcel(request, pager);
		}else{
			return viewTemplate;

		}
	}



	public void uploadFile(HttpServletRequest request) {
		String uploadPath = "C:\\upload";
			try {
				FileItemFactory factory = new DiskFileItemFactory();
				ServletFileUpload upload = new ServletFileUpload(factory);
				List<FileItem> items = upload.parseRequest(request);// 得到所有的文件
				Iterator<FileItem> itr = items.iterator();
				while (itr.hasNext()) {// 依次处理每个文件
					FileItem item = (FileItem) itr.next();
					String fileName = item.getName();// 获得文件名，包括路径
					String fieldName = item.getFieldName();
					if (fileName != null) {
						File fullFile = new File(item.getName());
						File savedFile = new File(uploadPath, fullFile.getName());
						item.write(savedFile);

						System.err.println(fieldName + "==" + fileName);
					}
				}
				System.out.print("upload succeed");
			} catch (Exception e) {
				e.printStackTrace();
			}
	}





	public List<SysAttach> uploadFile(HttpServletRequest request, SysAttach tpl) {
		List<SysAttach> rtnList = new ArrayList<SysAttach>();

		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		if (isMultipart == true) {
			try {
				FileItemFactory factory = new DiskFileItemFactory();
				ServletFileUpload upload = new ServletFileUpload(factory);
				List<FileItem> items = upload.parseRequest(request);// 得到所有的文件
				Iterator<FileItem> itr = items.iterator();
				while (itr.hasNext()) {// 依次处理每个文件
					FileItem item = (FileItem) itr.next();
					String fileName = item.getName();// 获得文件名，包括路径
					String fieldName = item.getFieldName();
					if (fileName != null && tpl.getFieldName().equals(fieldName)) {
						String uploadPath = "C:\\upload\\" + StringUtils.getNowTimes("yyyyMMdd") ;
						File fullFile = new File(item.getName());
						File savedFile = new File(uploadPath, fullFile.getName());
						item.write(savedFile);
						SysAttach attach = new SysAttach(tpl);

						attach.setFileName(fullFile.getName());
						rtnList.add(attach);
					}
				}
				System.out.print("upload succeed");
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			System.out.println("the enctype must be multipart/form-data");
		}
		return rtnList;
	}
















	public List<SysAttach> upload(HttpServletRequest request)
			throws Exception {
		List<SysAttach> attList = new ArrayList<SysAttach>();

			CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
					request.getSession().getServletContext());
			// 判断 request 是否有文件上传,即多部分请求
			if (multipartResolver.isMultipart(request)) {
				MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
				Iterator<String> iterator = multiRequest.getFileNames();
				while (iterator.hasNext()) {
					MultipartFile multiFile = multiRequest.getFile(iterator.next());
					attList.add(service.uploadFile(multiFile));
				}
			}else{
				System.err.println("isMultipart=====false");
			}
		return attList;
	}
	

/*
	public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String filename = request.getParameter("filename");

		filename = StringUtils.unescape(filename);
		// 设置文件MIME类型
		response.setContentType(request.getServletContext().getMimeType(filename));
		// 设置Content-Disposition

		String[] fileItems = filename.split("/");
		String file = StringUtils.unescape(fileItems[3]);

		if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
			file = new String(fileItems[3].getBytes("UTF-8"), "ISO8859-1");// firefox浏览器
		} else if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
			file = StringUtils.escape(fileItems[3]);
			// file = URLEncoder.encode(fileItems[3], "UTF-8");//IE浏览器
			// response.reset();//如果有换行，对于文本文件没有什么问题，但是对于其它格
		}

		response.setContentType("application/octet-stream");
		response.setHeader("Content-Disposition", "attachment;filename=\"" + file + "\"");
		// 读取目标文件，通过response将目标文件写到客户端
		// 获取目标文件的绝对路径
		String fullFileName = request.getServletContext().getRealPath("/") + filename;
		// System.out.println(fullFileName);
		// 读取文件
		InputStream in = new FileInputStream(fullFileName);
		OutputStream out = response.getOutputStream();

		// 写文件
		int b;
		while ((b = in.read()) != -1) {
			out.write(b);
		}

		in.close();
		out.close();
	}
	*/
	
	 
		/**
	     * 向指定URL发送GET方法的请求
	     * 
	     * @param url
	     *            发送请求的URL
	     * @param param
	     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
	     * @return URL 所代表远程资源的响应结果
	     */
	    public static Map<String ,Object> sendGet(String url, String param) {
	        String result = "";
	        BufferedReader in = null;
	        try {
	            String urlNameString = url ;
	            URL realUrl = new URL(urlNameString);
	            // 打开和URL之间的连接
	            URLConnection connection = realUrl.openConnection();
	            // 设置通用的请求属性
	            connection.setRequestProperty("accept", "*/*");
	            connection.setRequestProperty("connection", "Keep-Alive");
	            connection.setRequestProperty("user-agent",
	                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
	            // 建立实际的连接
	            connection.connect();
	            // 获取所有响应头字段
	            Map<String, List<String>> map = connection.getHeaderFields();
	            // 遍历所有的响应头字段
	            for (String key : map.keySet()) {
	                System.out.println(key + "--->" + map.get(key));
	            }
	            // 定义 BufferedReader输入流来读取URL的响应
	            in = new BufferedReader(new InputStreamReader(
	                    connection.getInputStream()));
	            String line;
	            while ((line = in.readLine()) != null) {
	                result += line;
	            }
	            System.out.println(result);
	        } catch (Exception e) {
	            System.out.println("发送GET请求出现异常！" + e);
	            e.printStackTrace();
	        }
	        // 使用finally块来关闭输入流
	        finally {
	            try {
	                if (in != null) {
	                    in.close();
	                }
	            } catch (Exception e2) {
	                e2.printStackTrace();
	            }
	        }
	        return (Map<String ,Object>)JSONObject.fromObject(result);
	    }
	    
		
	    /** 
	     * 发起https请求并获取结果 
	     *  
	     * @param requestUrl 请求地址 
	     * @param requestMethod 请求方式（GET、POST） 
	     * @param outputStr 提交的数据 
	     * @return JSONObject(通过JSONObject.getString(key)的方式获取json对象的属性值) 
	     */  
	    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {  
	        JSONObject jsonObject = null;  
	        StringBuffer buffer = new StringBuffer();  
	        try {  
	            // 创建SSLContext对象，并使用我们指定的信任管理器初始化  
	            TrustManager[] tm = { new MyX509TrustManager() };  
	            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");  
	            sslContext.init(null, tm, new java.security.SecureRandom());  
	            // 从上述SSLContext对象中得到SSLSocketFactory对象  
	            SSLSocketFactory ssf = sslContext.getSocketFactory();  
	      
	            URL url = new URL(requestUrl);  
	            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();  
	            httpUrlConn.setSSLSocketFactory(ssf);  
	      
	            httpUrlConn.setDoOutput(true);  
	            httpUrlConn.setDoInput(true);  
	            httpUrlConn.setUseCaches(false);  
	            // 设置请求方式（GET/POST）  
	            httpUrlConn.setRequestMethod(requestMethod);  
	      
	            if ("GET".equalsIgnoreCase(requestMethod))  
	                httpUrlConn.connect();  
	      
	            // 当有数据需要提交时  
	            if (null != outputStr) {  
	                OutputStream outputStream = httpUrlConn.getOutputStream();  
	                // 注意编码格式，防止中文乱码  
	                outputStream.write(outputStr.getBytes("UTF-8"));  
	                outputStream.close();  
	            }  
	      
	            // 将返回的输入流转换成字符串  
	            InputStream inputStream = httpUrlConn.getInputStream();  
	            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
	            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
	      
	            String str = null;  
	            while ((str = bufferedReader.readLine()) != null) {  
	                buffer.append(str);  
	            }  
	            bufferedReader.close();  
	            inputStreamReader.close();  
	            // 释放资源  
	            inputStream.close();  
	            inputStream = null;  
	            httpUrlConn.disconnect();  
	            jsonObject = JSONObject.fromObject(buffer.toString());  
	        } catch (ConnectException ce) {  
	        } catch (Exception e) {  
	        }  
	        return jsonObject;  
	    }  
		
		
		
		
		
		
	   


}
